#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAssembly.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkCellData.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <vtkPicker.h>
#include <vtkLight.h>
#include <vtkLightActor.h>
#include <vtkNamedColors.h>
#include <vtkProperty.h>
#include <vtkAssemblyPath.h>
vtkSmartPointer<vtkAssembly> CreateRubiksCube()
{
    vtkSmartPointer<vtkAssembly> cubeAssembly = vtkSmartPointer<vtkAssembly>::New();

    double pos[3] = {0.0, 0.0, 0.0};
    double offset = 1.2;

    // Create 9 cubes for each face
    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            for (int k = 0; k < 3; ++k)
            {
                // 每个正方体,相同的面染相同的颜色
                vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();
                cubeSource->SetXLength(1.0);
                cubeSource->SetYLength(1.0);
                cubeSource->SetZLength(1.0);
                // 设置每一个正方体的中心
                cubeSource->SetCenter(pos);
                cubeSource->Update();

                vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
                transform->RotateX(45.0);
                transform->RotateY(45.0);
                transform->RotateZ(45.0);

                cubeAssembly->SetUserTransform(transform);

                vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
                mapper->SetInputConnection(cubeSource->GetOutputPort());

                vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
                actor->SetMapper(mapper);
                cubeAssembly->AddPart(actor);

                vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
                // 设置每个元素的组成分量
                colors->SetNumberOfComponents(3);
                // 将颜色数组命名
                colors->SetName("Colors");
                // 颜色数组中包含6种颜色
                colors->InsertNextTuple3(255, 255, 255); // 白色
                colors->InsertNextTuple3(255, 255, 0);   // 黄色
                colors->InsertNextTuple3(255, 0, 0);     // 红色
                colors->InsertNextTuple3(255, 165, 0);   // 橙色
                colors->InsertNextTuple3(0, 128, 0);     // 绿色
                colors->InsertNextTuple3(0, 0, 255);     // 蓝色

                // getcelldata与立方体的面相关联
                // 得到的面都按照上面的颜色数组染色
                vtkPolyData *cubePolyData = cubeSource->GetOutput();
                cubePolyData->GetCellData()->SetScalars(colors);

                pos[0] += offset;
            }
            pos[0] = 0.0;
            pos[1] += offset;
        }
        pos[1] = 0.0;
        pos[2] += offset;
    }

    return cubeAssembly;
}

// void FindAssemblyByPosition(vtkAssembly *assembly, const double targetPosition[3], std::vector<vtkAssembly *> &foundAssemblies)
// {
//     // 创建一个 vtkPropCollection 对象来存储 assembly 中的所有成员
//     vtkPropCollection *props = vtkPropCollection::New();
//     assembly->GetActors(props); // 这里假设你希望获取的是 vtkActor 对象，你可以根据需要修改为其他类型的对象

//     // 遍历 props 中的所有成员 
//     vtkCollectionSimpleIterator pit;
//     props->InitTraversal(pit);
//     for (vtkProp *prop = props->GetNextProp(pit); prop != nullptr; prop = props->GetNextProp(pit))
//     {
//         vtkAssembly *subAssembly = vtkAssembly::SafeDownCast(prop);
//         if (subAssembly)
//         {
//             // 如果当前成员是一个 vtkAssembly 对象，则递归遍历其中的子成员
//             FindAssemblyByPosition(subAssembly, targetPosition, foundAssemblies);
//         }
//         else
//         {
//             vtkProp3D *prop3D = vtkProp3D::SafeDownCast(prop);
//             if (prop3D)
//             {
//                 // 获取当前成员的位置
//                 double position[3];
//                 prop3D->GetPosition(position);

//                 // 如果当前成员的位置与目标位置匹配，将其转换为 vtkAssembly 并添加到 foundAssemblies 中
//                 if (IsPositionEqual(position, targetPosition))
//                 {
//                     foundAssemblies.push_back(assembly);
//                 }
//             }
//         }
//     }

//     // 释放 vtkPropCollection 对象
//     props->Delete();
// }

int main()
{
    vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();
    // 创建渲染器
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();

    // 创建窗口
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(640, 480);
    // 创建交互器
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    // 创建装配体
    // assembly不允许 拷贝构造和赋值运算符
    vtkSmartPointer<vtkAssembly> assembly = vtkSmartPointer<vtkAssembly>::New();
    assembly = CreateRubiksCube();

    // 将装配体添加到渲染器
    renderer->AddActor(assembly);

    // 设置背景颜色
    renderer->SetBackground(0.1, 0.2, 0.4);

    // vtkSmartPointer<CustomInteractorStyle> style = vtkSmartPointer<CustomInteractorStyle>::New();
    // renderWindowInteractor->SetInteractorStyle(style);
    // 想实现按键控制不同层进行旋转,自定义键盘事件处理函数
    // vtkSmartPointer<vtkLight> light = vtkSmartPointer<vtkLight>::New();
    // light->PositionalOn();//设置聚光灯属性
    // light->SetLightTypeToHeadlight();
    // light->SetPosition(0.0, -3.0, 8.0);
    // light->SetFocalPoint(0.0,0.0,0.0);
    // light->SetIntensity(3.0);
    // // light->SetColor(colors->GetColor3d("DeepPink").GetData());

    // vtkSmartPointer<vtkLightActor> lightActor = vtkSmartPointer<vtkLightActor>::New();
    // lightActor->SetLight(light);
    // renderer->AddLight(light);
    // renderer->AddViewProp(lightActor);
    // 启动交互器
    renderWindow->Render();
    renderWindowInteractor->Start();

    return 0;
}
